package com.loeng.framework.dict.core;

import cn.hutool.core.util.ObjectUtil;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.loeng.framework.common.core.KeyValue;
import com.loeng.framework.common.util.cache.CacheUtils;
import com.loeng.module.system.api.dict.DictDataApi;
import com.loeng.module.system.api.dict.dto.DictDataRespDTO;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.time.Duration;
import java.util.List;

/**
 * 字典工具类
 *
 * @author loeng zhuo
 */
@Slf4j
public class DictFrameworkUtils {

    /**
     * 字典 Api 接口
     * {@link com.loeng.framework.dict.config.LoengDictAutoConfiguration 启动类中 进行值的注入}
     * 因为 工具类中 静态方法如果想用 dictDataApi ，，
     *  则 dictDataApi 属性也必须是静态的，但 @Resource 如法注入静态属性
     *  所以，在 启动类中，将 dictDataApi 的值注入到静态属性中
     */
    private static DictDataApi dictDataApi;

    /**
     * 字典数据为空的默认值
     */
    public static void init(DictDataApi dictDataApi) {
        DictFrameworkUtils.dictDataApi = dictDataApi;
        log.info("[init][初始化 DictFrameworkUtils 成功]");
    }

    /**
     * DictDataRespDTO
     */
    private static final DictDataRespDTO DICT_DATA_NULL = new DictDataRespDTO();

    /**
     * 针对 {@link #parseDictDataValue(String, String)} 的缓存
     */
    private static final LoadingCache<KeyValue<String, String>, DictDataRespDTO> PARSE_DICT_DATA_CACHE =
            CacheUtils.buildAsyncReloadingCache(Duration.ofMillis(1), new CacheLoader<KeyValue<String, String>, DictDataRespDTO>() {
                @Override
                public DictDataRespDTO load(KeyValue<String, String> key) throws Exception {
                    return ObjectUtil.defaultIfNull(dictDataApi.parseDictData(key.getKey(), key.getValue()), DICT_DATA_NULL);
                }
            });

    /**
     * 针对 {@link #getDictDataLabelList(String)} 的缓存
     */
    private static final LoadingCache<String, List<String>> GET_DICT_DATA_LIST_CACHE = CacheUtils.buildAsyncReloadingCache(
            // 过期时间 1 分钟
            Duration.ofMinutes(1L),
            new CacheLoader<String, List<String>>() {
                @Override
                public List<String> load(String dictType) {
                    return dictDataApi.getDictDataLabelList(dictType);
                }
            });


    /**
     * 解析字典数据
     *
     * @param dictType  字典类型
     * @param label 字典数据
     * @return 解析后的字典数据
     */
    @SneakyThrows
    public static String parseDictDataValue(String dictType, String label) {
        return PARSE_DICT_DATA_CACHE.get(new KeyValue<>(dictType, label)).getValue();
    }

    /**
     * 获得字典数据列表
     *
     * @param dictType 字典类型
     * @return 字典数据列表
     */
    @SneakyThrows
    public static List<String> getDictDataLabelList(String dictType) {
        return GET_DICT_DATA_LIST_CACHE.get(dictType);
    }

}
